package com.oot2d.util;

import com.oot2d.entity.Entity;
import com.oot2d.entity.NPC;
import org.yaml.snakeyaml.Yaml;
import com.oot2d.world.World;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class WorldManager {
    public static World currentWorld;
    private static World[] worlds;
    private static NPC[] npcs;
    private static Entity[] entities;

    private static boolean debug = true;

    public static void init()
    {
        parseWorlds();
        parseNPCs();
        parseEntities();
    }

    //Parse world data from YAML file
    private static void parseWorlds()
    {
        ArrayList<World> m = new ArrayList<World>();
        List<Map<String, Object>> w = null;

        //Development
        if (debug) {
            try {
                InputStream data = new FileInputStream(new File("res/data/world.yml"));
                Yaml yaml = new Yaml();
                w = (List<Map<String, Object>>) yaml.load(data);
            } catch (FileNotFoundException e) {
                System.err.println(e.getMessage());
            }
        }

        //Production
        else {
            InputStream data = WorldManager.class.getClassLoader().getResourceAsStream("res/data/world.yml");
            Yaml yaml = new Yaml();
            w = (List<Map<String, Object>>) yaml.load(data);
        }

        if (w != null) {
            for (Map<String, Object> o : w) {
                m.add(new World((String)o.get("map1"), (String)o.get("map2"), o.get("spawn")));
            }
        }

        worlds = m.toArray(new World[0]);
    }

    //Parse NPC data from YAML file
    private static void parseNPCs()
    {
        ArrayList<NPC> m = new ArrayList<NPC>();
        List<Map<String, Object>> w = null;

        //Development
        if (debug) {
            try {
                InputStream data = new FileInputStream(new File("res/data/npc.yml"));
                Yaml yaml = new Yaml();
                w = (List<Map<String, Object>>) yaml.load(data);
            } catch (FileNotFoundException e) {
                System.err.println(e.getMessage());
            }
        }

        //Production
        else {
            InputStream data = WorldManager.class.getClassLoader().getResourceAsStream("res/data/npc.yml");
            Yaml yaml = new Yaml();
            w = (List<Map<String, Object>>) yaml.load(data);
        }

        if (w != null) {
            for (Map<String, Object> o : w) {
                NPC n = new NPC((String)o.get("sprite"), (Integer)o.get("width"), (Integer)o.get("height"),
                    (Boolean)o.get("enemy"), (Integer)o.get("health"), (Integer)o.get("bbwidth"),
                    (Integer)o.get("bbheight"), (Integer)o.get("bbxoff"), (Integer)o.get("bbyoff"),
                    ((List<List<Object>>)o.get("anims")).size());

                n.addAnims((List<List<Object>>)o.get("anims"));
                m.add(n);
            }
        }

        npcs = m.toArray(new NPC[0]);
    }

    //Parse entity data from YAML file
    private static void parseEntities()
    {
        ArrayList<Entity> m = new ArrayList<Entity>();
        List<Map<String, Object>> w = null;

        //Development
        if (debug) {
            try {
                InputStream data = new FileInputStream(new File("res/data/entity.yml"));
                Yaml yaml = new Yaml();
                w = (List<Map<String, Object>>) yaml.load(data);
            } catch (FileNotFoundException e) {
                System.err.println(e.getMessage());
            }
        }

        //Production
        else {
            InputStream data = WorldManager.class.getClassLoader().getResourceAsStream("res/data/entity.yml");
            Yaml yaml = new Yaml();
            w = (List<Map<String, Object>>) yaml.load(data);
        }

        if (w != null) {
            for (Map<String, Object> o : w) {
                m.add(new Entity((String)o.get("sprite"), (Integer)o.get("width"), (Integer)o.get("height")));
            }
        }

        entities = m.toArray(new Entity[0]);
    }

    public static void loadWorld(int id)
    {
        worlds[id].load();
        currentWorld = worlds[id];
    }

    public static Entity loadEntity(int id)
    {
        return new Entity(entities[id]);
    }

    public static NPC loadNPC(int id)
    {
        return new NPC(npcs[id]);
    }

    public static ArrayList<NPC> queryNPCs(float x, float y, float w, float h, int z)
    {
        ArrayList<NPC> a = new ArrayList<NPC>();
        ArrayList<NPC> n = currentWorld.getNPCs(z);

        for (NPC i : n) {
            if ((i.getX() >= (x - i.getWidth()) && i.getX() <= (x + w)) &&
                (i.getY() >= (y - i.getHeight()) && i.getY() <= (y + h)))
                a.add(i);
        }

        return a;
    }
}
